/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package race.model;

import java.io.IOException;
import java.util.Random;
import java.util.Vector;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.game.Sprite;
import javax.microedition.lcdui.game.TiledLayer;
import race.util.BackgroundUtil;

/**
 *
 * @author BBXP
 */
public class Racer {
    public static final int WIDTH =24;
    public static final int HEIGHT = 30;
    private int posX;
    private int posY;
    private float direction = 0;
    private int speed = 0;
    private int maxSpeed = 20;
    private int acceleration = 2;
    private int deceleration = 1;
    private Sprite mySprite;
    private Sprite collisionSprite;
    private Sprite targetSprite;
    private int finishingLine;
    private boolean alive = true;
    private boolean finished = false;
    private boolean accelerating = false;
    private boolean decelerating = false;
    private Random r = new Random();
    private int randomTurning = 0;
    private int speedLevelUpCounter = 0;
    private int speedLevelDownCounter = 0;
    private int startPosX ;
    private int startPosY;
    private boolean offensive = false;

    private TiledLayer foreCollisionLayer;

    public Racer(int initX, int initY, int acceleration, int deceleration, int finishingLine, int id){
        this.finishingLine = finishingLine;
        this.posX = initX;
        this.posY = initY;
        this.startPosX = initX;
        this.startPosY = initY;
        this.acceleration = acceleration;
        this.deceleration = deceleration;
        try {
            mySprite = new Sprite(Image.createImage("/images/player_"+id+".png"), WIDTH, HEIGHT);
            collisionSprite = new Sprite(Image.createImage("/images/collision_sprite_small.png"), 5, 15);
            mySprite.setPosition(posX, posY);
            collisionSprite.setPosition(posX, posY);
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    public boolean isFinished(){
        return finished;
    }

    public void explode(){
        alive = false;
    }

    public void turnLeft(){
        if(speed != 0 && !finished){
            mySprite.setFrame(1);
            direction = -5;
        }
    }
    public void turnRight(){
        if(speed != 0 && !finished){
            mySprite.setFrame(2);
            direction = 5;
        }
    }

    public void limitTheSpeed(){
        if(speed > (maxSpeed * 0.3)){
            speed -= 5;
            speedLevelUpCounter = 0;
        }
        
    }

    public void goStraight (){
         mySprite.setFrame(0);
        direction = 0;
    }
    public void accelerate(){
        if(!finished){
            decelerating = false;
            accelerating = true;
        }
    }

    public int getX(){
        return posX;
    }

    public int getY(){
        return posY;
    }
    public void decelerate(){
        if(!finished){
            accelerating = false;
            decelerating = true;
        }
    }
    public void keepSteady(){
        accelerating = false;
        decelerating = false;
        
    }

    private void leftBounce(){
        speed -= 1;
        if(speed < 0){
            speed = 0;
        }
        
    }
    private void rightBounce(){
        speed -= 1;
        if(speed < 0){
            speed = 0;
        }
        
    }

    public void update(){
        if(posY <= finishingLine){
            finished = true;
            keepSteady();
        }
        if(accelerating){
            speedLevelDownCounter = 0;
            speedLevelUpCounter++;
            if(speedLevelUpCounter > 5){
                speedLevelUpCounter = 0;
                if(speed < maxSpeed){
                    speed += acceleration;
                }
            }
        }else if(decelerating){
            speedLevelUpCounter = 0;
            speedLevelDownCounter++;
            if(speedLevelDownCounter > 3){
                speedLevelDownCounter = 0;
                speed -= deceleration;
                if(speed < 0){
                    speed = 0;
                }
            }
        }else{
            
        }
        posX += direction;
        if(posX < BackgroundUtil.RODA_LEFT_LIMIT){
            posX = BackgroundUtil.RODA_LEFT_LIMIT;
            leftBounce();
        }else if(posX > BackgroundUtil.ROAD_RIGHT_LIMIT - WIDTH){
            posX = BackgroundUtil.ROAD_RIGHT_LIMIT - WIDTH;
            rightBounce();
        }
        collisionSprite.setPosition(posX, posY);
        posY -= speed;
        mySprite.setPosition(posX, posY);
        
    }

    public Sprite getSprite(){
        return mySprite;
    }
    public int getSpeed(){
        return speed;
    }
    public boolean isAccelerating(){
        return accelerating;
    }
    public boolean isDeceleration(){
        return decelerating;
    }
    public boolean isTurningLeft(){
        return direction == -1;
    }
    public boolean isTurningRight(){
        return direction == 1;
    }
    public Sprite getCollisionSprite(){
        return collisionSprite;
    }

    public void bounceOffToLeft(){
        posX -= 8;
    }

    public void bounceOffToRight(){
        posX += 8;
    }

    public void initAutoControl(TiledLayer foreCollisionLayer){
        this.foreCollisionLayer = foreCollisionLayer;
    }

    public void autoControl(TiledLayer collisionLayer){
        
        accelerate();
        
        boolean leftWallNear = posX-5 < BackgroundUtil.RODA_LEFT_LIMIT;
        boolean rightWallNear = posX + 5 > BackgroundUtil.ROAD_RIGHT_LIMIT - Racer.WIDTH;
        if(leftWallNear || rightWallNear){
            randomTurning = 0;
        }
        if(leftWallNear){
            turnRight();
            return;
        }else if(rightWallNear){
            turnLeft();
            return;
        }
        if(collisionSprite.collidesWith(foreCollisionLayer, false)){
            
            if(randomTurning != 0){
                if(randomTurning == -1){
                    turnLeft();
                }else{
                    turnRight();
                }
            }else{
                if(r.nextInt(2) == 0){
                    randomTurning = -1;
                    turnLeft();
                }else{
                    randomTurning = 1;
                    turnRight();
                }
            }
        }else{
           if(targetSprite != null && speed > maxSpeed * 0.4 && offensive){
                strageyMove();
           }else{
               goStraight();
           }
        }
    }

    public void setOffensive(boolean isOffensive){
        offensive = isOffensive;
    }

    public void strageyMove(){
        if(collisionSprite.getX() < targetSprite.getX()-5){
            turnRight();
        }else if(collisionSprite.getX() > targetSprite.getX()+targetSprite.getWidth()){
            turnLeft();
        }
    }

    public void setTargetSprite(Sprite s){
        this.targetSprite = s;
    }

    public void maxSpeed(){
        speed = maxSpeed;
    }

    public void reset(){
        this.posX = startPosX;
        this.posY = startPosY;
        speed = 0;
        randomTurning = 0;
        finished = false;
        direction = 0;
        goStraight();
        accelerating = false;
        decelerating = false;
    }
}
